﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ReadeAssetManager
{
    public partial class frmWarranty : Form
    {
        private AMSServiceRef.WarrantyData _warr;
        private AMSServiceRef.Asset _asset;
        private AMSServiceRef.User _user;
        private const string INVALID_INPUT = "The warranty type and service number fields cannot be empty.  Please re-enter.";
        private const string VERIFY_DELETE = "You are about to delete this warranty record.\n\n" +
                                             "Are you sure you want to delete this record?";
        private const string ERROR_LOAD_WARR = "An error occurred while loading this warranty record.";
        
        /// <summary>
        /// Constructor.
        /// This overload is used to create a new Warranty record.
        /// </summary>
        /// <param name="CurrentAsset">[AMSServiceRef.Asset] The asset record that will contain the new
        /// Schedule record.</param>
        public frmWarranty(AMSServiceRef.Asset CurrentAsset)
        {
            InitializeComponent();
            _asset = CurrentAsset;
            _user = _asset.Owner;
            _warr = new AMSServiceRef.WarrantyData();
            _warr.BaseItem = _asset;
            this.Text = _asset.Name + " New Warranty";
        }

        /// <summary>
        /// Constructor.
        /// This overload is used to modify an existing Warranty record.
        /// </summary>
        /// <param name="CurrentWarranty">[AMSServiceRef.WarrantyData] The existing Warranty record to view
        /// or modify.</param>
        public frmWarranty(AMSServiceRef.WarrantyData CurrentWarranty)
        {
            InitializeComponent();
            _warr = CurrentWarranty;
            _user = _warr.BaseItem.Owner;
            PopulateFormOptions();
            PopulateFormValues();
        }

        /// <summary>
        /// AddWarrantyToAsset
        /// Determines whether this Warranty record already exists in the Asset.  If not, adds the Warranty
        /// record to the Asset warranties list.  Otherwise, simply returns.
        /// </summary>
        private void AddWarrantyToAsset()
        {
            if (_warr.BaseItem.Warranties != null)
            {
                foreach (AMSServiceRef.WarrantyData w in _warr.BaseItem.Warranties)
                {
                    if (w.Equals(_warr))
                        return;
                }
            }
            else
                _warr.BaseItem.Warranties = new List<AMSServiceRef.WarrantyData>();

            _warr.BaseItem.Warranties.Add(_warr);
        }

        /// <summary>
        /// PopulateFormValues
        /// Fills the userform fields from the global AMSServiceRef.WarrantyData object.  Displays an
        /// error if the warranty data could not be accessed (such as the Warranty is not instantiated).
        /// </summary>
        private void PopulateFormValues()
        {
            try
            {
                txtType.Text = _warr.Type;
                txtServNum.Text = _warr.ServiceNumber;
                txtComments.Text = _warr.Comments;
                dtpStartDate.Value = _warr.Start;
                dtpEndDate.Value = _warr.End;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ERROR_LOAD_WARR + "\n\n" + ex.Message, "Error Loading Warranty Record");
            }
        }

        /// <summary>
        /// PopulateFormOptions
        /// Loads the form title and dropdown menu bar domains.
        /// </summary>
        private void PopulateFormOptions()
        {
            ToolStripMenuItem[] items;

            this.Text = _warr.BaseItem.Name + " Schedule: " + _warr.Type;

            // Load all available images
            if (_warr.Images != null)
            {
                items = new ToolStripMenuItem[_warr.Images.Count];
                for (int i = 0; i < _warr.Images.Count; i++)
                {
                    AMSServiceRef.AMSImage a = _warr.Images[i];
                    items[i] = CreateMenuItem(a, "mnuAssetImages" + a.ID, a.Caption, new EventHandler(LoadImageItem));
                }
                mnuWarrRecordsImages.DropDownItems.AddRange(items);
            }
            else
                _warr.Images = new List<AMSServiceRef.AMSImage>();
        }

        /// <summary>
        /// CreateMenuItem
        /// Creates a ToolStripMenuItem to represent the domain record for this Warranty.
        /// </summary>
        /// <param name="TagItem">[object] The domain object to be added to the MenuItem tag.</param>
        /// <param name="Name">[string] The MenuItem name.</param>
        /// <param name="Text">[string] The MenuItem text.</param>
        /// <param name="ClickEvent">[EventHandler] The event that should be raised when the user clicks the MenuItem.</param>
        /// <returns>[ToolStripMenuItem] The menu item representing this domain object.</returns>
        private ToolStripMenuItem CreateMenuItem(object TagItem, string Name,
                                                string Text, EventHandler ClickEvent)
        {
            ToolStripMenuItem tsmi = new ToolStripMenuItem();
            tsmi.Name = Name;
            tsmi.Text = Text;
            tsmi.Tag = TagItem;
            tsmi.Click += ClickEvent;

            return tsmi;
        }

        /// <summary>
        /// LoadImageItem
        /// EventHandler for an Image MenuItem.  This functionality is not implemented.
        /// </summary>
        /// <param name="sender">[object] The MenuItem that raised this event.</param>
        /// <param name="e">[EventArgs] The standard event arguments for a Click event.</param>
        private void LoadImageItem(object sender, EventArgs e)
        {
            // Open the images form with ((ToolStripMenuItem)sender).Tag
            MessageBox.Show("Images are not yet implemented.", "Not Implemented");
        }

        /// <summary>
        /// PopulateWarrantyFromFields
        /// Loads all values from the userform into the current AMSServiceRef.WarrantyData object.
        /// </summary>
        private void PopulateWarrantyFromFields()
        {
            _warr.Type = txtType.Text;
            _warr.Start = dtpStartDate.Value;
            _warr.End = dtpEndDate.Value;
            _warr.ServiceNumber = txtServNum.Text;
            _warr.Comments = txtComments.Text;
        }

        /// <summary>
        /// SaveWarranty
        /// Validates the user input, hydrates the object from the userform controls, and attempts
        /// to save the warranty record.  If the save is successful, attempts to add a new WarrantyData 
        /// to the asset's warranties list and refreshes the frmMain asset list.
        /// </summary>
        /// <returns>[bool] True if the warranty record was successfully saved, otherwise false.</returns>
        private bool SaveWarranty()
        {
            if (IsValidInput())
            {
                PopulateWarrantyFromFields();
                AMSServiceRef.AMSServiceClient c = new AMSServiceRef.AMSServiceClient();
                AMSServiceRef.WarrantyData tmpw = c.SaveWarranty(_warr);
                if (tmpw != null)
                {
                    _warr = tmpw;
                    _user = _warr.BaseItem.Owner;
                    AddWarrantyToAsset();
                    ((frmMain)MdiParent).RefreshAssetList(_user);
                    return true;
                }
                return false;
            }
            else
            {
                MessageBox.Show(INVALID_INPUT);
                return false;
            }
        }

        /// <summary>
        /// IsValidInput
        /// Validates the user input based on database requirements.
        /// </summary>
        /// <returns>[bool] True if the input is valid, otherwise false.</returns>
        private bool IsValidInput()
        {
            return (txtType.Text.Length > 0) &&
                   (txtServNum.Text.Length > 0);
        }

        private void mnuWarrWarrDelete_Click(object sender, EventArgs e)
        {
            if (_warr.ID > 0)
            {
                if (MessageBox.Show(VERIFY_DELETE, "Delete Warranty Record", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                {
                    AMSServiceRef.AMSServiceClient c = new AMSServiceRef.AMSServiceClient();
                    if (c.DeleteWarranty(_warr))
                    {
                        _warr.BaseItem.Warranties.Remove(_warr);
                        ((frmMain)MdiParent).RefreshAssetList(_user);
                        this.Close();
                    }
                    else
                        MessageBox.Show("Unable to delete warranty record. " + _warr.Type + " dated " +
                                            _warr.Start.ToShortDateString() + ".");
                }
            }
        }

        private void mnuWarrWarrSave_Click(object sender, EventArgs e)
        {
            if (!SaveWarranty())
                MessageBox.Show("Unable to save warranty record.");
        }

        private void mnuWarrWarrSaveClose_Click(object sender, EventArgs e)
        {
            if (!SaveWarranty())
            {
                if (MessageBox.Show("Unable to save changes.  Do you still want to close?", "Save Failed", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No)
                    return;
            }
            this.Close();
        }
    }
}
